/**
 * @file sh_test.c
 * 
 * @date: 2021-08-10
 * 
 * @author: lyfan
 * 
 * test application
**/
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <sys/syscall.h>
#include <time.h>

#include "csdn_codereader.h"

static void SF_LogHex(uint8_t *buf, int len)
{
	int i = 0;

	while(i < len){
		fprintf(stdout, "%02x ", buf[i]);
		if ((i+1) % 8 == 0){
			fprintf(stdout, "\n");
		}
		i++;
	}
	fprintf(stdout, "\n");

	return ;
}


int main(int argc, char **argv)
{
	int ret, i, barcount, picfd, rlen, datalen;
	CodeReaderParamSet	stBarAlgPara, stBarAlgParaRead;
	CodeReaderResult *pResultNode;
	struct timespec tpstart, tpend;
	long timedif;
	char *results_ptr = NULL;
	unsigned char *pimage_addr = NULL;

	printf("start init\n");
	memset(&stBarAlgPara, 0, sizeof(stBarAlgPara));
	memset(&stBarAlgParaRead, 0, sizeof(stBarAlgParaRead));
	stBarAlgPara.nFlag = 0;
	stBarAlgPara.nBarcodeCount = 0;
	stBarAlgPara.nCodeSymbology = 0x10001;
	stBarAlgPara.nBarcodeDgtNum = 0;
	stBarAlgPara.nBarcodeDgtNumExt = 0;
	stBarAlgPara.nBarcodeValidity = 0;
	stBarAlgPara.nBarcodeValidityExt = 0;
	stBarAlgPara.nMultiPkgDetect = 0;
	stBarAlgPara.nTimeLimitMillis = 0;
	stBarAlgPara.nBarcodeSearchDepth = 0;
	stBarAlgPara.n2DcodeSearchDepth = 0;
	stBarAlgPara.n2DcodeCount = 0;

	picfd = open("/root/test/pic_460.grey", O_RDONLY);		//raw picture size: 4096*3072
	if (picfd < 0){
		printf("open pic_460.grey err - %s\n", strerror(errno));
		return -1;
	}
	pimage_addr = malloc(4096*3072);
	if (pimage_addr == NULL){
		printf("malloc err - %s\n", strerror(errno));
		return -1;
	}

	datalen = 0;
	while(datalen < 4096*3072){
		rlen = read(picfd, pimage_addr+datalen, 4096 <= (4096*3072) ? 4096 : (4096*3072 - datalen));
		if (rlen < 0 && errno != EAGAIN && errno != EINTR){
			printf("read error: %s\n", strerror(errno));
			free(pimage_addr);
			close(picfd);
			return -1;
		}
		datalen += rlen;
	}

	close(picfd);
	ret = Csdn_ModuleLoad_Entry();
	if (ret != WX_eSuccess){
		printf("Csdn_ModuleLoad_Entry err - %d\n", ret);
		free(pimage_addr);
		return -1;
	} else{
		printf("Csdn_ModuleLoad_Entry ok!\n");
	}

	ret = CsdnCR_Init_Entry(1, 4096, 3072);
	if (ret != WX_eSuccess){
		printf("CsdnCR_Init_Entry err - %d\n", ret);
	} else{
		printf("CsdnCR_Init_Entry ok!\n");
	}

	ret = CsdnCR_SetParam_Entry(1, stBarAlgPara);
	if (ret != WX_eSuccess){
		printf("CsdnCR_SetParam_Entry err - %d\n", ret);
	} else{
		printf("CsdnCR_SetParam_Entry ok!\n");
	}

	ret = CsdnCR_GetParam_Entry(1, &stBarAlgParaRead);
	if (ret != WX_eSuccess){
		printf("CsdnCR_GetParam_Entry err - %d\n", ret);
	} else{
		printf("CsdnCR_GetParam_Entry ok!\n");
	}

	if (memcmp(&stBarAlgPara, &stBarAlgParaRead, sizeof(stBarAlgPara)) != 0){
		printf("memcmp faild\nstBarAlgPara:\n");
		SF_LogHex((uint8_t *)&stBarAlgPara, sizeof(stBarAlgPara));
		printf("\n\nstBarAlgParaRead:\n");
		SF_LogHex((uint8_t *)&stBarAlgParaRead, sizeof(stBarAlgPara));
	} else{
		printf("memcmp CodeReaderParam ok!\n");
	}
	
	for(i = 0; i < 30; i++){
		results_ptr = NULL;
		clock_gettime(CLOCK_REALTIME, &tpstart);
		ret = CsdnCR_Process_Entry(1, pimage_addr, 4096, 3072, &results_ptr);
		clock_gettime(CLOCK_REALTIME, &tpend);
		timedif = 1000*(tpend.tv_sec - tpstart.tv_sec) + (tpend.tv_nsec - tpstart.tv_nsec)/1000000;
		printf("i: %d, barcode recognized algorithm time cost: %ld ms\n", i, timedif);
		if (ret <= 0){
			printf("no barcode recognized: %d!!!\n", ret);
		} else{
			if (NULL == results_ptr){
				printf("Unexpected results ptr. results_ptr=%p\n", results_ptr);
			}else{
				if (-1 == *results_ptr){
					printf("Not FIND!!!\n");
				} else if(0 == *results_ptr){
					printf("Not READ!!!\n");
				} else if(*results_ptr < 0){
					printf("Unexpected return. ret=%d\n", *results_ptr);
				} else{
					pResultNode = (CodeReaderResult *)(results_ptr + sizeof(int));
					for(barcount = 0; barcount < *results_ptr; ++barcount) {
						if(NULL == pResultNode)
							break;
						printf("Code %3d>>>>>%s<<<<<\n", barcount, &pResultNode->strCode1stChar);
						printf("type: 0x%x, char num: %d\n\n", pResultNode->nCodeSymbology, pResultNode->nCodeCharNum);
						pResultNode = pResultNode->next;
					}
				}
			}
		}
	}

	ret = CsdnCR_Release_Entry(1);
	if (ret != WX_eSuccess){
		printf("CsdnCR_Release_Entry err - %d\n", ret);
	} else{
		printf("CsdnCR_Release_Entry ok!\n");
	}

	ret = Csdn_ModuleUnload_Entry();
	if (ret != WX_eSuccess){
		printf("Csdn_ModuleUnload_Entry err - %d\n", ret);
	} else{
		printf("Csdn_ModuleUnload_Entry ok!\n");
	}

	printf("release over.\n");
	free(pimage_addr);
	while(getchar() != '\n') sleep(1);

	return ret;
}



